/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.treeeditpart;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.treeeditpart.diagramview.DiagramItemEditPart;
import com.cea.papyrus.core.treeeditpart.diagramview.DiagramListRootEditPart;
import com.cea.papyrus.core.treeeditpart.pseudoelement.BehavioredClassifierBehaviorsGroup;
import com.cea.papyrus.core.treeeditpart.pseudoelement.EventsGroup;
import com.cea.papyrus.core.treeeditpart.pseudoelement.ImportsGroup;
import com.cea.papyrus.core.treeeditpart.pseudoelement.PackageBehaviorsGroup;
import com.cea.papyrus.core.treeeditpart.pseudoelement.ProfileApplicationsGroup;
import com.cea.papyrus.core.treeeditpart.pseudoelement.TriggersGroup;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;


/**
 * Factory that maps model elements to TreeEditParts.
 * TreeEditParts are used in the outline view.
 */
public class TreeEditPartFactory implements EditPartFactory {

	/** Model Manager associated to the editor */
	protected ModelManager modelManager;

	/** debug channel */
	protected static final int channel = 23;

	/**
	 * 
	 * 
	 * @param modelmanager 
	 */
	public TreeEditPartFactory(ModelManager modelmanager){
		this.modelManager=modelmanager;
	}
	/* 
	 * Create EditPart for the requested model object.
	 */
	/**
	 * 
	 * 
	 * @param context 
	 * @param model 
	 * 
	 * @return 
	 */
	public EditPart createEditPart(EditPart context, Object model) {


		if (model instanceof Resource) {
			return new DiagramListRootEditPart((Resource)model,modelManager);
		}

		if (model instanceof Diagram) {

			DiagramTreeEditPart newEditPart = null;

			if (context instanceof ElementTreeEditPart) {
				newEditPart = new DiagramTreeEditPart((Diagram) model, modelManager, (ElementTreeEditPart) context);
			}
			else if(context instanceof DiagramListRootEditPart) {
				return  new DiagramItemEditPart((Diagram) model, modelManager);
			
			} else {
				Debug.error(this, "EditPart createEditPart(EditPart context, Object model) context is not a ElementTreeEditPart", channel);
			}

			return newEditPart;

		}
		/*********************ClassDiagram********************************************/
		// RS: no more specific edit part for Parameters. Notifications are handled in the standard tree edit part
//		else if (model instanceof org.eclipse.uml2.uml.Parameter) {		
//			return new ParameterTreeEditPart((org.eclipse.uml2.uml.Parameter)model,modelManager);
//		}
//		else if (model instanceof org.eclipse.uml2.uml.Property) {		
//			return new PropertyTreeEditPart((org.eclipse.uml2.uml.Property)model,modelManager);
//		}
		else if (model instanceof org.eclipse.uml2.uml.TemplateParameter) {
			return new TemplateParameterTreeEditPart((org.eclipse.uml2.uml.TemplateParameter)model,modelManager) ; 
		}
		else if (model instanceof org.eclipse.uml2.uml.RedefinableTemplateSignature) {
			return new RedefinableTemplateSignatureTreeEditPart((org.eclipse.uml2.uml.RedefinableTemplateSignature)model,modelManager) ;
		}
		else if (model instanceof org.eclipse.uml2.uml.TemplateSignature) {
			return new TemplateSignatureTreeEditPart((org.eclipse.uml2.uml.TemplateSignature)model,modelManager) ;
		}
		else if (model instanceof org.eclipse.uml2.uml.TemplateBinding) {
			return new TemplateBindingTreeEditPart((org.eclipse.uml2.uml.TemplateBinding)model,modelManager) ;
		}

		/*****************************************************************/

		else if (model instanceof org.eclipse.uml2.uml.Element) {		
			return new ElementTreeEditPart(model, modelManager);
		}
		else if (model instanceof ModelManager) {		
			return new ModelManagerTreeEditPart((ModelManager)model);
		}
		else if(model instanceof ImportsGroup) {
			return new GroupingImportsTreeEditPart(((ImportsGroup)model), modelManager);
		}
		else if(model instanceof ProfileApplicationsGroup) {
			return new GroupingProfileApplicationsTreeEditPart(((ProfileApplicationsGroup)model), modelManager);
		}
		else if(model instanceof TriggersGroup){
			return new GroupingTriggersTreeEditPart((TriggersGroup)model, modelManager);
		}
		else if(model instanceof EventsGroup){
			return new GroupingEventsTreeEditPart((EventsGroup)model, modelManager);
		}
		else if(model instanceof BehavioredClassifierBehaviorsGroup){
			return new GroupingBehaviorsTreeEditPart((BehavioredClassifierBehaviorsGroup)model, modelManager);
		} 
		else if(model instanceof PackageBehaviorsGroup){
			return new GroupingBehaviorsTreeEditPart((PackageBehaviorsGroup)model, modelManager);
		}
		else {
			return null;
		}
	}

//	/**
//	* Returns the edit part or tree of edit part for a specific UML element
//	* @param context
//	* @param element
//	* @return
//	*/
//	public EditPart createEditPart(EditPart context, org.eclipse.uml2.uml.Element element) {
//	// default rule : avoid stackoverflow...
//	if(context instanceof GroupingImportsTreeEditPart) {
//	return new ElementTreeEditPart(element, modelManager);
//	}

//	switch(element.eClass().getClassifierID()) {
//	// specific case for element and package imports
//	case UMLPackage.ELEMENT_IMPORT:
//	case UMLPackage.PACKAGE_IMPORT:
//	Namespace namespace;
//	if(element instanceof ElementImport) {
//	namespace = ((ElementImport)element).getImportingNamespace();
//	} else {
//	namespace = ((PackageImport)element).getImportingNamespace();
//	}
//	// retrieve parent edit part => test if it has more than one element import.
//	// if yes, it should retrieve the tree edit part that groups the imports
//	// if no one exists, create it
//	// else add the edit part to its parent

//	// test if parent edit part has more than one element or package import
//	if(hasMoreImportsThan(namespace, MAX_IMPORT_GROUP_NUMBER)) {
//	GroupingImportsTreeEditPart groupEditPart = getGroupingImportsTreeEditPart(context, namespace);
//	// now creates the edit part for the current element with new context
//	return createEditPart(groupEditPart, element);

//	} else {
//	// it has no more than the minimum grouping number, generate the simple edit part
//	return new ElementTreeEditPart(element, modelManager);
//	}
//	default : 
//	return new ElementTreeEditPart(element, modelManager);
//	}
//	}


}